package api

import (
	"crypto/rand"
	"encoding/json"
	"fmt"
	"strconv"
	"time"
)

const alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01"
const mask = 32 - 1
const PreviewerIdLength = 20

func GenRandString() (string, error) {
	r := make([]byte, PreviewerIdLength) // no padding
	_, err := rand.Read(r)
	if err != nil {
		return "", err
	}

	for i := 0; i < PreviewerIdLength; i++ {
		r[i] = alphabet[r[i]&mask]
	}
	return string(r), nil
}

// ParseIntValue parses the the int in val or, if there is an error, returns the
// specified default value
func ParseIntValue(val string, fallback int) int {
	if len(val) > 0 {
		parsedVal, parseErr := strconv.Atoi(val)
		if parseErr == nil && parsedVal >= 0 {
			return parsedVal
		}
	}
	return fallback
}

// ParseIntOrDurationValue parses the the duration in val or, if there is an error, returns the
// specified default value
func ParseIntOrDurationValue(val string, fallback time.Duration) time.Duration {
	if len(val) > 0 {
		parsedVal, parseErr := strconv.Atoi(val)
		if parseErr == nil && parsedVal >= 0 {
			return time.Duration(parsedVal) * time.Second
		}
	}

	duration, durationErr := time.ParseDuration(val)
	if durationErr != nil {
		return fallback
	}

	return duration
}

// ParseBoolValue parses the the boolean in val or, if there is an error, returns the
// specified default value
// func ParseBoolValue(val string, fallback bool) bool {
// 	if len(val) > 0 {
// 		return val == "true"
// 	}
// 	return fallback
// }
func ParseBoolValue(val interface{}, fallback bool) bool {
	str := fmt.Sprintf("%v", val)
	switch str {
	case "1", "t", "T", "true", "TRUE", "True":
		return true
	case "0", "f", "F", "false", "FALSE", "False":
		return false
	}
	return fallback
}

// ParseString verifies the string in val is not empty. When empty, it returns the
// specified default value
func ParseString(val string, fallback string) string {
	if len(val) > 0 {
		return val
	}
	return fallback
}

func ParseStringSlice(val string, fallback []string) []string {
	if len(val) > 0 {
		var ret []string
		err := json.Unmarshal([]byte(val), &ret)
		if err == nil {
			return ret
		}
	}
	return fallback
}

func ParseIntSlice(val string, fallback []int) []int {
	if len(val) > 0 {
		var ret []int
		err := json.Unmarshal([]byte(val), &ret)
		if err == nil {
			return ret
		}
	}
	return fallback
}
